﻿using System.Security.Cryptography;
using System.Text;

namespace MyMD5
{
    /// <summary>
    /// Md5加密帮助类
    /// </summary>
    public class MyMd5Helper
    {
        /// <summary>
        /// MD5加密，得到的字符串使用十六进制类型格式
        /// </summary>
        /// <param name="pwd">明文(待加密)</param>
        /// <returns>加密后的密文</returns>
        public static string Md5Encrypt_x(string pwd)
        {
            return Md5Encrypt(pwd, "x");
        }

        /// <summary>
        /// MD5加密，得到的字符串使用十六进制类型格式
        /// </summary>
        /// <param name="pwd">明文(待加密)</param>
        /// <returns>加密后的密文</returns>
        public static string Md5Encrypt_x2(string pwd)
        {
            return Md5Encrypt(pwd, "x2");
        } 

        /// <summary>
        /// MD5加密，得到的字符串使用十六进制类型格式
        /// </summary>
        /// <param name="pwd">明文(待加密)</param>
        /// <returns>加密后的密文</returns>
        public static string Md5Encrypt_X(string pwd)
        {
            return Md5Encrypt(pwd, "X");
        } 
        
        /// <summary>
        /// MD5加密，得到的字符串使用十六进制类型格式
        /// </summary>
        /// <param name="pwd">明文(待加密)</param>
        /// <returns>加密后的密文</returns>
        public static string Md5Encrypt_X2(string pwd)
        {
            return Md5Encrypt(pwd, "X2");
        }

        /// <summary>
        /// MD5加密，得到的字符串使用十六进制类型格式
        /// </summary>
        /// <param name="pwd">明文(待加密)</param>
        /// <param name="type">加密类别 x、x2、X、X2 </param>
        ///  X 表示大写, x 表示小写，X2和x2表示不省略首位为0的十六进制数字
        /// <returns>加密后的密文</returns>
        public static string Md5Encrypt(string pwd, string type)
        {
            string result = string.Empty;
            // MD5类是抽象类
            MD5 md5 = MD5.Create();
            // 需要将字符串转成字节数组
            byte[] buffer = Encoding.UTF8.GetBytes(pwd);
            // 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择
            byte[] md5buffer = md5.ComputeHash(buffer);
            // 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
            foreach (byte b in md5buffer)
            {
                // 得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写（X）则格式后的字符是大写字符 
                // 但是在和对方测试过程中,发现我这边的MD5加密编码,经常出现少一位或几位的问题；
                // 后来分析发现是 字符串格式符的问题, X 表示大写, x 表示小写, 
                // X2和x2表示不省略首位为0的十六进制数字；
                result += b.ToString(type);
            }
            return result;
        }

    }
}
